home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
Online
/
SpeakFreely
/
src
/
lpc10
/
analys.c
next >
Wrap
C/C++ Source or Header
|
2000-05-18
|
7KB
|
243 lines
/*******************************************************************
*
* ANALYS Version 50
*
*******************************************************************/
#include <stdlib.h>
#include "lpcdefs.h"
#include "config.ch"
/* Constants
* NF = Number of frames
* AF = Frame in which analysis is done
* OSLEN = Length of the onset buffer
* LTAU = Number of pitch lags
* SBUFL, SBUFH = Start and end index of speech buffers
* LBUFL, LBUFH = Start and end index of LPF speech buffer
* MINWIN, MAXWIN = Min and Max length of voicing (and analysis) windows
* PWLEN, PWINH, PWINL = Length, upper and lower limits of pitch window
* DVWINL, DVWINH = Default lower and upper limits of voicing window
*/
#define LPFILT_DELAY 15
#define NUM_VF 9
extern int tau[LTAU];
extern float lparray[LBUFH-LBUFL+1], ivarray[PWINH-PWINL+1];
extern float pearray[SBUFH-SBUFL+1], inarray[SBUFH-SBUFL+1];
extern float *inbuf, *pebuf, *lpbuf, *ivbuf;
extern int vwin[2][AF], awin[2][AF], voibuf[2][AF+1];
extern float rmsbuf[AF], amdf[LTAU], psi[MAXORD], rcbuf[MAXORD][AF];
extern float phi[MAXORD][MAXORD];
static float zpre[2]={0.0, 0.0};
analys( speech, voice, pitch, rms, rc )
float speech[];
float *rms, rc[];
int voice[2], *pitch;
{
/* Data Buffers
* INBUF Raw speech (with DC bias removed each frame)
* PEBUF Preemphasized speech
* LPBUF Low pass speech buffer
* IVBUF Inverse filtered speech
* OSBUF Indexes of onsets in speech buffers
* VWIN Voicing window indices
* AWIN Analysis window indices
* EWIN Energy window indices
* VOIBUF Voicing decisions on windows in VWIN
* RMSBUF RMS energy
* RCBUF Reflection Coefficients
*
* Pitch is handled separately from the above parameters.
* The following variables deal with pitch:
* MIDX Encoded initial pitch estimate for analysis frame
* IPITCH Initial pitch computed for frame AF (decoded from MIDX)
* PITCH The encoded pitch value (index into TAU) for the present
* frame (delayed and smoothed by Dyptrack)
*/
/* REAL INBUF(SBUFL:SBUFH), PEBUF(SBUFL:SBUFH)
REAL LPBUF(LBUFL:LBUFH), IVBUF(PWINL:PWINH) */
float abuf[MAXWIN], temp;
static float bias=0.;
static int osptr=1;
static int obound[AF];
static int ewin[2][AF];
int i, j, lanal;
int ipitch, minptr, maxptr, mintau, midx;
float ivrc[2];
static int osbuf[OSLEN], first=1;
#ifdef NN_VOICE
int vstart;
#else
int half;
#endif
if (first) {
first = 0;
for(i=0;i<OSLEN;i++)
osbuf[i] = 0;
for(i=0;i<AF;i++);
obound[i] = 0;
}
speech--;
/* Calculations are done on future frame due to requirements
* of the pitch tracker. Delay RMS and RC's 2 frames to give
* current frame parameters on return.
* Update all buffers
*/
for (i = SBUFL;i<=SBUFH-LFRAME;i++) {
inbuf[i] = inbuf[LFRAME+i];
pebuf[i] = pebuf[LFRAME+i];
}
for( i = PWINL; i<=PWINH-LFRAME; i++) {
ivbuf[i] = ivbuf[LFRAME+i];
}
for( i = LBUFL;i<=LBUFH-LFRAME;i++) {
lpbuf[i] = lpbuf[LFRAME+i];
}
/* loop below adjusted for C indexing */
j=1;
for( i = 1;i<=osptr-1;i++) {
if (osbuf[i-1] > LFRAME) {
osbuf[j-1]=osbuf[i-1]-LFRAME;
j++;
}
}
osptr=j;
voibuf[0][0] = voibuf[0][1];
voibuf[1][0] = voibuf[1][1];
for( i = 0;i<AF-1;i++) {
vwin[0][i] = vwin[0][i+1] - LFRAME;
vwin[1][i] = vwin[1][i+1] - LFRAME;
awin[0][i] = awin[0][i+1] - LFRAME;
awin[1][i] = awin[1][i+1] - LFRAME;
ewin[0][i] = ewin[0][i+1] - LFRAME;
ewin[1][i] = ewin[1][i+1] - LFRAME;
obound[i] = obound[i+1];
voibuf[0][i+1] = voibuf[0][i+2];
voibuf[1][i+1] = voibuf[1][i+2];
rmsbuf[i] = rmsbuf[i+1];
for( j = 0;j<ORDER;j++) {
rcbuf[j][i] = rcbuf[j][i+1];
}
}
/* Copy input speech, scale to sign+12 bit integers
* Remove long term DC bias. (This code can be removed
* if adequate high pass filtering and reliable A/D
* conversion is available)
*/
temp = 0;
for( i = 1;i<=LFRAME;i++){
inbuf[SBUFH-LFRAME+i] = *(speech+i)*4096. - bias;
temp += inbuf[SBUFH-LFRAME+i];
}
if( temp > LFRAME ) bias++;
if( temp < -LFRAME ) bias--;
/* Place Voicing Window */
i = SBUFH + 1 - LFRAME;
preemp( &inbuf[i-1], &pebuf[i-1], LFRAME, 0.4, zpre );
onset( pebuf, osbuf-1, &osptr);
placev(osbuf, osptr, &obound[AF-1],vwin);
/* The Pitch Extraction algorithm estimates the pitch for a frame
* of speech by locating the minimum of the average magnitude difference
* function (AMDF). The AMDF operates on low-pass, inverse filtered
* speech. (The low-pass filter is an 800 Hz, 19 tap, equiripple, FIR
* filter and the inverse filter is a 2nd-order LPC filter.) The pitch
* estimate is later refined by dynamic programming (DYPTRK). However,
* since some of DYPTRK's parameters are a function of the voicing
* decisions, a voicing decision must precede the final pitch estimation.
* See subroutines LPFILT, IVFILT, and TBDM.
*/
lpfilt31(&inbuf[LBUFH-1-PWLEN-1], &lpbuf[LBUFH+1-PWLEN-1]);
ivfilt( &lpbuf[PWINL-1], &ivbuf[PWINL-1], ivrc-1 ); /*C-shifted*/
tbdm( &ivbuf[PWINL-1], tau-1, amdf-1, &minptr, &maxptr, &mintau ); /*C-shifted*/
/* Voicing decisions are made for each half frame of input speech.
* An initial voicing classification is made for each half of the
* analysis frame, and the voicing decisions for the present frame
* are finalized. See subroutine VOICIN.
* The voicing detector (VOICIN) classifies the input signal as
* unvoiced (including silence) or voiced using the AMDF windowed
* maximum-to-minimum ratio, the zero crossing rate, energy measures,
* reflection coefficients, and prediction gains.
* The pitch and voicing rules apply smoothing and isolated
* corrections to the pitch and voicing estimates and, in the process,
* introduce two frames of delay into the corrected pitch estimates and
* voicing decisions.
*/
#ifndef NN_VOICE
for (half = 1;half<=2;half++) {
voicin( vwin, inbuf, lpbuf, half, amdf[minptr-1], amdf[maxptr-1], mintau, ivrc-1, obound-1, voibuf);
}
#else
vstart = PWINL + (PWLEN>>1) - (LFRAME>>1);
voicing(inbuf, lpbuf+LPFILT_DELAY, vstart, vstart+LFRAME-1, mintau, &voibuf[0][3], &voibuf[1][3]);
#endif
/* Find the minimum cost pitch decision over several frames
* given the current voicing decision and the AMDF array
*/
dyptrk(amdf-1, minptr, voibuf[1][AF], pitch, &midx );
ipitch = tau[midx-1];
/* Place spectrum analysis and energy windows */
placea( ipitch, voibuf/*-(AF+1)*/, obound[AF-1], vwin, awin, ewin);
/* Remove short term DC bias over the analysis window, Put result in ABUF */
lanal = awin[1][AF-1] + 1 - awin[0][AF-1];
dcbias(lanal, &pebuf[awin[0][AF-1]]-1, abuf-1 );
/* Compute RMS over integer number of pitch periods within the
* analysis window.
* Note that in a hardware implementation this computation may be
* simplified by using diagonal elements of PHI computed by MLOAD.
*/
energy( ewin[1][AF-1]-ewin[0][AF-1]+1, &abuf[ewin[0][AF-1]-awin[0][AF-1]]-1, &rmsbuf[AF-1] );
/* Matrix load and invert, check RC's for stability */
mload(lanal, abuf-1, phi, psi-1 );
invert(phi, psi, rcbuf);
rcchk(rcbuf);
/* Set return parameters */
voice[0] = voibuf[0][AF-2];
voice[1] = voibuf[1][AF-2];
*rms = rmsbuf[AF-3];
for(i = 1;i<=ORDER;i++)
rc[i] = rcbuf[i-1][AF-3];
}